package fun.coding.leetcode;

import java.util.ArrayList;
import java.util.List;

public class UniqueBinarySearchTreesII {

	public static void main(String[] args) {
		UniqueBinarySearchTreesII ubst = new UniqueBinarySearchTreesII();
		List<TreeNode> res = ubst.generateTrees(3);
	}
	// When only calculating values, use DP
	// When want solutions, use DFS/recursion
	public List<TreeNode> generateTrees(int n) {
		return helper(1, n);
	}
	
	public List<TreeNode> helper(int start, int end) {
		List<TreeNode> res = new ArrayList<TreeNode>();
		if (start > end) {
			res.add(null);
			return res;
		}
		
		// This is kind neat, recursion inside loop, when each node is root
		for (int i = start; i <= end; i++) {
			List<TreeNode> left = helper(start, i - 1);
			List<TreeNode> right = helper(i + 1, end);
			
			// Combine two subtrees, total tree is left * right
			for (TreeNode l : left) {
				for (TreeNode r : right) {
					TreeNode root = new TreeNode(i);
					root.left = l;
					root.right = r;
					res.add(root);
				}
			}
		}
		return res;
	}
}
